package coreservlets;

import java.util.concurrent.*;

/** A Runnable as an inner class (variation 3 of 3).
 *  <p>
 *  From <a href="http://courses.coreservlets.com/Course-Materials/">the
 *  coreservlets.com tutorials on JSF 2, PrimeFaces, Ajax, jQuery, GWT, Android,
 *  Spring, Hibernate, JPA, RESTful Web Services, Hadoop, 
 *  servlets, JSP, and Java 7 and Java 8 programming</a>.
 */

public class App3 extends SomeClass {
  public App3() {
    ExecutorService taskList =
      Executors.newFixedThreadPool(100);
    taskList.execute(new Counter(6));
    taskList.execute(new Counter(5));
    taskList.execute(new Counter(4));
    taskList.shutdown();
  }
  
  private void pause(double seconds) {
    try {
      Thread.sleep(Math.round(1000.0 * seconds));
    } catch (InterruptedException ie) { }
  }

  // The run method can easily access methods and instance variables in the
  // main class, since it is in an inner class inside the main class. If you
  // start multiple threads and "run" modifies instance variables of the outer
  // class, you have to worry about race conditions. It is very simple to
  // pass arguments to run by passing them to the inner class constructor
  // and then having run refer to them.

  private class Counter implements Runnable {
    private final int loopLimit;

    public Counter(int loopLimit) {
      this.loopLimit = loopLimit;
    }

    public void run() {
      for(int i=0; i<loopLimit; i++) {
        String threadName = Thread.currentThread().getName();
        System.out.printf("%s: %s%n", threadName, i);
        pause(Math.random()); // Sleep for up to 1 second
      }
    }
  }
}